//
//  TSCMyUtil.m
//  Tsc_IOS
//
//  Created by Rio on 15-5-4.
//  Copyright (c) 2015年 idream. All rights reserved.
//

#import "TSCSDK.h"
#import <CommonCrypto/CommonDigest.h> // MD5加密使用
#import "TSCAppDelegate.h"

@implementation TSCMyUtil

/*
 * NSDictionary转换为NSString
 *
 * @author Rio
 * @date 2015-05-04
 */
+(NSString *) dictionary2String:(NSDictionary *)dic {
    NSData * data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
    // TODO 这里为什么不能用宏定义？
    NSString * string = [[NSString alloc] initWithData:data encoding:O_ENCODING];
    return string;
}

/*
 * 顾名思义
 *
 * @author Rio
 * @date 2015-05-05
 */
+(NSString *) implodeWithGlue:(NSString *)glue array:(NSArray *)array {
    NSMutableString * builder = [[NSMutableString alloc]init];
    for(NSInteger i = 0, max = [array count]; i < max ; i++) {
        if (i != 0) {
            [builder appendString:glue];
        }
        // 注：array中有可能是NSNumber而不仅仅是NSString，所以不能用appendString，而要用appendFormat
//        [builder appendString:[array objectAtIndex:i]];
        [builder appendFormat:@"%@", array[i]];
    }
    
    return builder;
}

/**
 * 顾名思义，同PHP
 *
 * @author Rio
 * @date 2015-05-15
 */
+ (NSArray *) explodeString:(NSString *)string delimiter:(NSString *)delimiter {
    return [string componentsSeparatedByString:delimiter];
    //    if (TextUtils.isEmpty(string) == true) {
    //        return new String[0];
    //    } else {
    //        return string.split(delimiter);
    //    }
}

/*
 * 为NSArray的每一个NSString类型的元素添加引号。使用场景：拼装insert sql时，为防止列名/列值和关键字冲突
 *
 * 注：列名应该添加`
 * 注：列值应该添加"或者'
 * 注：如果列值类型为NSInteger，则添加"或者'都可以正常执行sql
 *
 * @author Rio
 * @date 2015-05-06
 */
+(NSArray *) addGlue2Array:(NSString *)glue array:(NSArray *)array {
    NSMutableArray * result = [[NSMutableArray alloc]init];
    for (NSString * e in array) {
        [result addObject:[NSString stringWithFormat:@"%@%@%@", glue, e, glue]];
    }
    
    return result;
}

/*
 * 判断一个字符串是否为空
 *
 * @author Rio
 * @date 2015-05-08
 */
+ (BOOL) isStringEmpty:(NSString *)string {
    if (string == nil || string == NULL) {
        return TRUE;
    }
    if ([string isKindOfClass:[NSNull class]]) {
        return TRUE;
    }
    if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
        return TRUE;
    }
    return FALSE;
}

/*
 * 判断一个数组是否为空
 *
 * @author Rio
 * @date 2015-05-25
 */
+ (BOOL) isArrayEmpty:(NSArray *)array {
    if (array == nil || [array count] == 0) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/**
 * 检查a是否为b的子集，即a中的全部元素都必须在b集合中。注：
 * <p>
 * 1. 数组元素类型可以任意，但必须支持equals()方法
 *
 * @author Rio
 * @date 2014-11-11
 *
 * @param aArr
 * @param bArr
 * @return
 */
+ (BOOL) isA:(NSArray *)aArr subsetOfB:(NSArray *)bArr {
checkNextA:
    //
    for (NSObject * ae in aArr) {
        for (NSObject * be in bArr) {
            // 如果a中的一个元素和b中的一个元素相等了，则继续检查下一个a元素
            if ([ae isEqual:be] == true) {
                goto checkNextA; // 2015-06-11 Rio OC中没有带lable的continue，只能用goto了！人生中第一次使用goto！
            }
        }
        
        // 代码运行到此处，表示这个a元素和b中的任意一个元素都不相同，可以认为a不是b的子集了
        return false;
    }
    
    // 代码运行到此处，表示已经将a中的所有元素都检查过了，都至少和b中的一个元素相同，可以认为a是b的子集了
    return true;
}

/**
 * @author Rio
 * @date 2015-05-14
 */
+ (NSString *) trim:(NSString *)string {
    return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

/**
 * 判断一个数组中，是否存在两个相同的元素。注：
 *
 * 1. 当数组中没有元素，或者仅有一个元素时，返回false，表示不存在相同的元素
 *
 * @author Rio
 * @date 2015-05-15
 */
+ (BOOL) hasSameElement:(NSArray* )array {
    NSInteger count = [array count];
    
    if (count >= 2) {
        for (NSInteger i = 0; i <= count - 2; i++) {
            NSString * e1 = array[i];
            
            for (NSInteger j = i + 1; j <= count - 1; j++) {
                NSString * e2 = array[j];
                
                if([e1 isEqualToString:e2] == true) {
                    return true;
                }
            }
        }
    }
    
    return false;
}

/**
 * 一段时间间隔后，执行一段代码
 *
 * @author Rio
 * @date 2015-05-21
 */
+ (void) executeBlockAfterTI:(CGFloat)ti block:(void (^)())block {
    // 异步线程中等待
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [NSThread sleepForTimeInterval:ti];
        
        // 回到主线程处理
        dispatch_async(dispatch_get_main_queue(), ^{
            block();
        });
    });
}

/**
 * 将UD中的内容全部清空。经试验resetStandardUserDefaults无法达到想要的效果，且如果默认的UD被重置了，所有VC都需要重新获得，这样就麻烦了，所以还是手工一个个删除吧。
 *
 * @author Rio
 * @date 2015-05-24
 */
+ (void) clearUD:(NSUserDefaults *)ud {
    NSDictionary * keyDic = [ud dictionaryRepresentation];
    
    for (NSString * key in [keyDic allKeys]) {
        [ud removeObjectForKey:key];
    }
    
    // 暂时由外层调用者自行同步！
    //    [ud synchronize];
}

/**
 * 生成一个范围在[min, max)之间的随机数
 *
 * 注：参考这篇文章：http://www.cnblogs.com/zeejun/archive/2012/07/22/2603329.html
 * 不过我认为不应该对(max-min+1)取余，而是应该对(max-min)取余。因为x%y的结果，是[0,y-1]，所以如果按照(max-min+1)取余，将得到两端封闭[]的区间，而不是左闭右开的[)区间
 *
 * @author Rio
 * @date 2015-05-21
 */
+ (long) generateRandNumScopedMin:(long)min max:(long)max {
    return (arc4random() % (max - min) + min);
}

/**
 * 加密密码
 *
 * @author Rio
 * @date 2015-05-22
 */
+ (NSString *) getMD5:(NSString *)string {
    const char *cStr = [string UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, strlen(cStr), result ); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            //            ,
            //            result[16], result[17], result[18], result[19],
            //            result[20], result[21], result[22], result[23],
            //            result[24], result[25], result[26], result[27],
            //            result[28], result[29], result[30], result[31]
            ];
}

/**
 * 获得当前的ViewController
 *
 * @author Rio
 * @date 2015-05-25
 */
+ (UIViewController *) getCurrentViewController {
    // 方法：AppDelegate的window，其rootViewController恰好时一个nvc，获得这个nvd的可见vc
    return ((UINavigationController *)[[UIApplication sharedApplication].delegate window].rootViewController).visibleViewController;
}


/**
 * 将ShareSDK的用户类型，转码为服务器端存储的用户类型
 *
 * @author Rio
 * @date 2015-09-14
 */
+ (NSInteger) translateShareType2Tsc3UserType:(ShareType)shareType {
    switch (shareType) {
        case ShareTypeQQSpace:
            return DB_DB_THIRD_PARTY_TYPE_QQ;
            break;
        case ShareTypeSinaWeibo:
            return DB_DB_THIRD_PARTY_TYPE_SINA_WEIBO;
            break;
        default:
            NSAssert(YES == NO, @"[E]%s: 将ShareType转换为服务器端存储的三方用户类型时，传入了暂不支持的用户类型[%i]，请来添加代码！", __FUNCTION__, shareType);
            return DB_DB_THIRD_PARTY_TYPE_UNSUPPORT;
            break;
    }
}

/**
 * 将系统自己的登录数据，及所有三方（ShareSDK）方平台的登录信息，全部清除
 *
 * @author Rio
 * @date 2015-09-14
 */

+ (void) logoutAllWithUserDefaults:(NSUserDefaults *)ud {
    // 清空登录状态
    [TSCMyUtil clearUD:ud];
    [ud synchronize];
    
    // 清除三方登录信息
    [ShareSDK cancelAuthWithType:ShareTypeQQSpace];
    [ShareSDK cancelAuthWithType:ShareTypeSinaWeibo];
}

/**
 * 获得某个view相对于当前显示窗口的绝对frame
 *
 * @author Rio
 * @date 2015-05-25
 */
+ (CGRect) getAbsoluteFrame:(UIView *)view {
    NSAssert(view.superview != nil, @"[E]%s: 转换坐标系时，原始坐标系不存在（view没有superView）！", __FUNCTION__);
    
    return [view.superview convertRect:view.frame toView:[TSCMyUtil getCurrentViewController].view];
}

/**
 * 获得某个view相对于当前显示窗口的绝对center
 *
 * @author Rio
 * @date 2015-05-25
 */
+ (CGPoint) getAbsoluteCenter:(UIView *)view {
    NSAssert(view.superview != nil, @"[E]%s: 转换坐标系时，原始坐标系不存在（view没有superView）！", __FUNCTION__);
    
    return [view.superview convertPoint:view.center toView:[TSCMyUtil getCurrentViewController].view];
}

/**
 * 获得某个view相对于当前显示窗口的绝对center
 *
 * @author Rio
 * @date 2015-05-26
 */
+ (CGRect) getAbsoluteBounds:(UIView *)view {
    NSAssert(view.superview != nil, @"[E]%s: 转换坐标系时，原始坐标系不存在（view没有superView）！", __FUNCTION__);
    
    return [view.superview convertRect:view.bounds toView:[TSCMyUtil getCurrentViewController].view];
}

/**
 * 获得项目总体目录路径
 *
 * 目录结构：
 *
 * \外部存储\com.idream.tsc\Pictures
 *
 * @author Rio
 * @date 2014-07-22
 *
 * @param fileType
 * @return
 */
+ (NSString *) getFileDir:(NSInteger)fileType {
    // 注：APP只能访问以下三个目录
    //  Documents, Temp or Cache
    // 如果访问了其他目录，将导致创建目录/文件失败。报错：Operation not permitted
    // 参考：http://stackoverflow.com/questions/18573894/permission-to-create-folder-on-iphone
    //    NSString * projectDir = NSHomeDirectory();
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * projectDir = [paths lastObject];
    
    // 注：为了避免相册扫描到APP自有的图片，在Picture之前加一个点（或者在Picture中加一个.nomedia空文件），以使此文件夹以隐藏文件夹的形式存在
    // 注：IOS中，.nomedia有用。当将文件夹以.nomedia方式命名后，将导致在Finder中无法查看（除非开启显示隐藏文件）
    // 注：IOS中，即便不用.nomedia，保存在APP Document中的图片文件，也是无法从相册中查看的
    switch (fileType) {
        case FileTypeImgTemp:
            return [NSString stringWithFormat:@"%@/Pictures/temp", projectDir];
        case FileTypeImgFace:
            return [NSString stringWithFormat:@"%@/Pictures/face", projectDir];
        case FileTypeImgPic:
            return [NSString stringWithFormat:@"%@/Pictures/pic", projectDir];
        case FileTypeImgChat:
            return [NSString stringWithFormat:@"%@/Pictures/chat", projectDir];
        case FileTypeImgCover:
            return [NSString stringWithFormat:@"%@/Pictures/cover", projectDir];
        case FileTypeImgSys:
            return [NSString stringWithFormat:@"%@/Pictures/sys", projectDir];
        case FileTypeApk:
            return [NSString stringWithFormat:@"%@/apk", projectDir];
            
        default:
            NSLog(@"[E]%s: 获得文件路径时，fileType参数值错误！", __FUNCTION__);
            return nil;
    }
}

/**
 * 根据文件类型获得文件后缀
 *
 * @author Rio
 * @date 2014-07-24
 *
 * @param fileType
 * @return
 */
+ (NSString *) getFileSuffix:(NSInteger)fileType {
    switch (fileType) {
        case FileTypeImgTemp:
            return @".jpg";
        case FileTypeImgFace:
            return @".jpg";
        case FileTypeImgPic:
            return @".jpg";
        case FileTypeImgChat:
            return @".jpg";
        case FileTypeImgCover:
            return @".jpg";
        case FileTypeImgSys:
            return @".jpg";
        case FileTypeApk:
            return @".apk";
        default:
            NSLog(@"[E]%s: 获得文件后缀时，fileType参数值错误！", __FUNCTION__);
            return nil;
    }
}

/**
 * 创建一个（临时）文件。如果创建失败，返回null。
 *
 * 整个项目创建文件时，都应该使用此方法，以保证全项目组统一的目录结构。
 *
 * @date 2014-06-15
 * @author Rio
 *
 * @param fileType
 * @param fileName
 *            文件名 如果不输入，则生成随机文件名，并根据文件类型添加后缀；如果输入（输入的文件名应该已经包含后缀），就使用输入的
 * @param overwrite
 *            true-如果设备上已存在同名文件，则覆盖；false-如果设备上已存在同名文件，创建文件失败，返回null
 *
 * @return
 */
+ (NSString *) makeFile:(NSInteger)fileType fileName:(NSString *)fileName overwrite:(BOOL)overwrite {
    
    // 获得目录及文件名
    NSString * dir = [TSCMyUtil getFileDir:fileType];
    NSString * suffix = [TSCMyUtil getFileSuffix:fileType];
    //    NSDateFormatter * df = [[NSDateFormatter alloc]init];
    //    df.dateFormat = @"yyyyMMdd_HHmmss";
    //    fileName = [TSCMyUtil isStringEmpty:fileName] == YES ? [NSString stringWithFormat:@"%@%@", [df stringFromDate:[NSDate date]], suffix] : fileName;
    NSString * randFileName = [NSString stringWithFormat:@"%li", [TSCMyUtil generateRandNumScopedMin:10000000000000 max:99999999999999]]; // 还是按照yyyyMMddHHmmss的位数，生成随机数
    fileName = [TSCMyUtil isStringEmpty:fileName] == YES ? [NSString stringWithFormat:@"%@%@", randFileName, suffix] : fileName;
    
    // 获得文件路径
    NSString * filePath = [dir stringByAppendingPathComponent:fileName];
    
    // 创建目录
    NSFileManager * fm = [NSFileManager defaultManager];
    NSError * err;
    BOOL result;
    //    if ([fm fileExistsAtPath:dir] == NO) {
    // 注：IOS中，不用校验文件夹是否已经存在了，因为依据IOS API的建议，不建议“预先校验”，而是直接进行IO操作，直到报错为止，因为“预先校验”的结果可能不准确。
    // 注：IOS中，重复创建目录，依然是成功的
    result = [fm createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:&err];
    
    if (result == NO) {
        NSLog(@"[E]%s: 创建文件时，建立目录失败！目标目录：%@。错误信息：%@", __FUNCTION__, dir, err);
        return nil;
    }
    //    }
    
    // 创建文件
    result = [fm createFileAtPath:filePath contents:nil attributes:nil];
    if (result) {
        return filePath;
    } else {
        NSLog(@"[E]%s: 创建文件时失败！", __FUNCTION__);
        return nil;
    }
}

/**
 * 将文件从一个位置copy至项目统一指定的位置。目前仅用在以下情况下使用：
 * <p>
 * 1. 聊天中从相册选择图片上传后，再次查看此聊天前，为避免从SER再次下载该图片， 就事先copy一份原图到url指定的位置。
 * <p>
 * 2. 用户更新头像后，为了是菜单点点点能立即从face文件夹下重新读取头像，所以copy一份到face文件夹下。注：如果头像是拍照得来的，
 * 那么从temp中copy一份到face；如果头像是从相册选择而来，则从图片在相册的位置copy一份到face。
 *
 * @author Rio
 * @date 2014-08-25
 * @param fileType
 * @param originalFilePath
 * @param overwrite
 * @param picUrl
 * @return
 */
+ (NSString *) copyFile:(NSInteger)fileType oldPath:(NSString *)oldFilePath overwrite:(BOOL)overwrite picUrl:(NSString *)picUrl {
    // 校验并获取输入参数
    // IOS：do nothing
    
    // 检查文件类型
    // 注：目前仅支持以下图片类型
    NSAssert(
             fileType == FileTypeImgChat
             ||
             fileType == FileTypeImgFace
             ||
             fileType == FileTypeImgPic
             , @"[E]%s: LinearLayout设置了非法的distribution！", __FUNCTION__); // 如果将来需要下载其他类型的文件（比如apk文件），继续添加...
    
    // 检查原文件是否存在
    NSFileManager * fm = [NSFileManager defaultManager];
    NSError * error;
    BOOL result;
    NSAssert([fm fileExistsAtPath:oldFilePath] == YES, @"[E]%s: 拷贝文件时，原文件不存在！", __FUNCTION__);
    
    // 获得目标路径
    NSString * newFilePath = @"";
    switch (fileType) {
        case FileTypeImgChat:
        case FileTypeImgFace:
        case FileTypeImgPic: {
            NSAssert([TSCMyUtil isStringEmpty:picUrl] == NO, @"[E]%s: 当fileType为IMG_CHAT/IMG_FACE/IMG_PIC时，第4个参数必须为picUrl！", __FUNCTION__);
            
            newFilePath = [TSCMyUtil fileUrl2FilePath:fileType fileUrl:picUrl thumbnailType:ThumbnailType0];
            
            NSAssert([TSCMyUtil isStringEmpty:newFilePath] == NO, @"[E]%s: 当fileType为IMG_CHAT/IMG_FACE/IMG_PIC时，根据fileUrl计算filePath失败！", __FUNCTION__);
            
            break;
        }
            // case Constants.FILE_TYPE.IMG_TEMP:
            // if ((params[3] instanceof String) == false) {
            // throw new IllegalArgumentException(
            // "当fileType为IMG_TEMP时，第4个参数必须为newFilePath！");
            // }
            // newFilePath = (String) params[3];
            // break;
            // 如果将来需要下载其他类型的文件（比如apk文件），继续添加...
    }
    
    // 检查原图路径是否和目标路径一样
    NSAssert([oldFilePath isEqualToString:newFilePath] == NO, @"[E]%s: 拷贝文件时，原文件路径和目标文件路径完全一致，均为[%@]！", __FUNCTION__, oldFilePath);
    
    // ===== 程序运行至此，原文件一定存在，且newFilePath必定不为空
    
    // 判断是否能被重写
    if (overwrite) {
        // 注：有可能只进行了空移除，忽略即可
        [fm removeItemAtPath:newFilePath error:&error];
    } else {
        NSAssert([fm fileExistsAtPath:newFilePath] == NO, @"[E]%s: 拷贝文件时，目标文件[%@]已存在，且指定overwrite为false！", __FUNCTION__, newFilePath);
    }
    
    // 如果目标文件所在的文件夹还不存在，则创建
    NSString * newFileDir = [newFilePath stringByDeletingLastPathComponent];
    result = [fm createDirectoryAtPath:newFileDir withIntermediateDirectories:YES attributes:nil error:&error];
    NSAssert(result == YES, @"[E]%s: 拷贝文件时，目标文件[%@]所在的目录不存在，创建此目录时失败！错误信息：%@", __FUNCTION__, newFilePath, error);
    
    // copy文件
    result = [fm copyItemAtPath:oldFilePath toPath:newFilePath error:&error];
    NSAssert(result == YES, @"[E]%s: 拷贝文件时，copy目标文件[%@]]失败！错误信息：%@", __FUNCTION__, newFilePath, error);
    
    NSLog(@"[I]%s: 拷贝文件成功。原文件[%@]，新文件[%@]", __FUNCTION__, oldFilePath, newFilePath);
    return newFilePath;
}

/**
 * 通过图片在图片服务器上的URL地址，转换获得图片存放在本地的文件名
 *
 * 可能的输入：
 *
 * http://tscpub.qiniudn.com/FllqF25Q479UJ1UTLaVKcssABfjr
 *
 * http://tscpubsys.qiniudn.com/shop_pic.jpeg
 *
 * http://qzapp.qlogo.cn/qzapp/1103586261/CCA03C0EEDCFDDEC772FC610EF79A14F/
 * 100
 *
 * http://ww4.sinaimg.cn/crop.61.0.339.339.1024/66776e6d
 * jw1ef06bmzy0jj20e609habr.jpg
 *
 * http://tp1.sinaimg.cn/2093186020/180/5598338969/1
 *
 * 输出：FllqF25Q479UJ1UTLaVKcssABfjr.jpg
 *
 * @author Rio
 * @date 2014-07-22
 * @param fileType
 * @param fileUrl
 * @return 如果fileUrl为空，或者转换不正确，返回空字符串
 * @see MyUtil#imgUrl2FilePath(String)
 */
+ (NSString *) fileUrl2FileName:(NSInteger)fileType fileUrl:(NSString *)fileUrl thumbnailType:(NSInteger)thumbnailType {
    
    if ([TSCMyUtil isStringEmpty:fileUrl] == NO) {
        // 获得文件名
        // 注：为了避免因三方图片服务器url变化而导致APP无法解析文件名称的问题，文件url到文件名的映射策略一律使用对url进行md5
        NSMutableString * name = [NSMutableString stringWithString:[TSCMyUtil getMD5:fileUrl]];
        
        // 根据缩略图类型，拼装文件名中的后缀
        switch (thumbnailType) {
            case ThumbnailType0:
                // 原图：do nothing
                break;
            case ThumbnailType1:
                [name appendString:@"_t1"];
                break;
            default:
                NSAssert(YES == NO, @"[E]%s: 文件URL[%@]向文件名转换时，输入了错误的缩略图类型[%li]！", __FUNCTION__, fileUrl, thumbnailType);
        }
        
        // 文件名：加一是为了不取到最后一个/
        // String name = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
        // 后缀
        NSString * suffix = [TSCMyUtil getFileSuffix:fileType];
        
        // 注：因为md5将所有文件url转换为md5字符串，且不带有任何后缀，所以不用以下复杂的拼装方法了，直接将文件名+后缀拼在一起即可
        NSMutableString * fileName = [[NSMutableString alloc]init];
        [fileName appendString:name];
        [fileName appendString:suffix];
        // 判断，如果自带后缀则无需添加，无后缀就添加后缀，如果url的文件名长度小于或者等于后缀长度则直接添加后缀
        //        if (name.length > suffix.length) {
        //            NSLog(@"kk:%@", [name substringWithRange:NSMakeRange(name.length - suffix.length, suffix.length)]);
        //            if ([[name substringWithRange:NSMakeRange(name.length - suffix.length, suffix.length)] compare:suffix options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        //                [fileName appendString:name];
        //            } else {
        //                [fileName appendString:name];
        //                [fileName appendString:suffix];
        //            }
        //        } else {
        //            // 2015-08-30 Rio 还是没搞懂，这个分支有何意义？
        //            [fileName appendString:name];
        //            [fileName appendString:suffix];
        //        }
        
        return fileName;
    } else {
        NSLog(@"[E]%s: 文件url转换为文件name时，fileUrl为空！", __FUNCTION__);
        return @"";
    }
    
}

/**
 * 通过图片在图片服务器上的URL地址，转换获得图片存放在本地的文件路径
 *
 * 可能的输入：
 *
 * http://tscpub.qiniudn.com/FllqF25Q479UJ1UTLaVKcssABfjr
 *
 * http://qzapp.qlogo.cn/qzapp/1103586261/CCA03C0EEDCFDDEC772FC610EF79A14F/
 * 100
 *
 * 输出：/storage/emulated/0/com.idream.tsc/Pictures/
 * FllqF25Q479UJ1UTLaVKcssABfjr.jpg
 *
 * @author Rio
 * @param fileType
 * @param fileUrl
 * @return 如果fileUrl为空，则返回空字符串
 * @see MyUtil#fileUrl2FileName(String)
 */
+ (NSString *) fileUrl2FilePath:(NSInteger)fileType fileUrl:(NSString *)fileUrl thumbnailType:(NSInteger)thumbnailType {
    if ([TSCMyUtil isStringEmpty:fileUrl] == NO) {
        return [[TSCMyUtil getFileDir:fileType] stringByAppendingPathComponent:[TSCMyUtil fileUrl2FileName:fileType fileUrl:fileUrl thumbnailType:thumbnailType]];
    } else {
        NSLog(@"[E]%s: 文件url转换为文件path时，fileUrl为空！", __FUNCTION__);
        return @"";
    }
}

/**
 * 判断一个字符串是否为url。判断标准为是否以http开头
 *
 * @author Rio
 * @date 2014-08-04
 * @param maybeUrl
 * @return
 */
+ (BOOL) isUrl:(NSString *)maybeUrl {
    return [maybeUrl hasPrefix:@"http"];
}

/**
 * 通过timestamp构造16位的日期字符串。yyyyMMddHHmmss
 *
 * @author Rio
 * @date 2014-08-06
 * @param timestamp
 * @param format
 */
+ (NSString *) getDateStrFromTs:(NSInteger)timestamp format:(NSString *)format {
    NSDate * date = [NSDate dateWithTimeIntervalSince1970:timestamp];
    
    NSDateFormatter * df = [[NSDateFormatter alloc]init];
    df.dateFormat = format;
    return [df stringFromDate:date];
}

/**
 * 通过yyyyMMddHHmmss获得timestamp
 *
 * @author Rio
 * @date 2014-12-04
 *
 * @param dateStr
 * @param format
 * @return 如果格式无法转换，将返回-1
 */
+(NSInteger) getTsFromDateStr:(NSString *)dateStr format:(NSString *)format {
    NSDateFormatter * df = [[NSDateFormatter alloc]init];
    df.dateFormat = format;
    
    return [df dateFromString:dateStr].timeIntervalSince1970;
}

/**
 * 通过今天的timestamp，获得明天（24小时之后）的timestamp
 *
 * @author Rio
 * @date 2014-12-05
 *
 * @param todayTs
 * @return
 */
+ (NSInteger) getTsTomorrow:(NSInteger)todayTs {
    return todayTs + 1 * 60 * 60 * 24;
}

/**
 * NSDate->日期字符串
 *
 * @author Rio
 * @date 2015-10-07
 */
+ (NSString *) date2String:(NSDate *)date format:(NSString *)format {
    NSDateFormatter * df = [[NSDateFormatter alloc]init];
    df.dateFormat = format;
    return [df stringFromDate:date];
}

/**
 * 日期字符串->NSDate
 *
 * @author Rio
 * @date 2015-10-07
 */
+ (NSDate *) string2Date:(NSString *)dateString format:(NSString *)format {
    NSDateFormatter * df = [[NSDateFormatter alloc]init];
    df.dateFormat = format;
    return [df dateFromString:dateString];
}

@end
